package xyz.bali16.application.controller;


import com.gitee.starblues.core.PluginInfo;
import xyz.bali16.application.core.enums.ApiEnum;
import xyz.bali16.application.core.model.Result;
import com.gitee.starblues.integration.application.PluginApplication;
import com.gitee.starblues.integration.operator.PluginOperator;
import com.gitee.starblues.integration.operator.upload.UploadParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import java.util.List;

import static xyz.bali16.application.core.model.Result.success;


@RestController
@RequestMapping(BaseController.API + "plugin")
@Api(tags = "插件管理接口")
@AllArgsConstructor
@Slf4j
public class PluginController extends BaseController {
    @Autowired
    private PluginOperator pluginOperator;
    @Autowired
    private final PluginApplication pluginApplication;

    @GetMapping
    @ApiOperation("获取插件列表")
    public Result<List<PluginInfo>> getPluginList() {
        return Result.success(ApiEnum.GET_SUCCESS, pluginOperator.getPluginInfo());
    }

    /**
     * 根据插件id启动插件
     *
     * @param id 插件id
     * @return 返回操作结果
     */
    @PostMapping("/start/{id}")
    @ApiOperation("启动插件")
    @ApiImplicitParam(name = "id", value = "插件id", paramType = "path", required = true)
    public Result<String> start(@PathVariable("id") String id) {
        try {
            if (pluginOperator.start(id)) {
                return Result.response(ApiEnum.OPERATE_SUCCESS, "启动成功");
            } else {
                return Result.response(ApiEnum.OPERATE_ERROR, "启动失败");
            }
        } catch (Exception e) {
            log.error("启动插件 '{}' 失败.", id, e);
            return Result.response(ApiEnum.OPERATE_ERROR, "启动失败." + e.getMessage());
        }
    }

    /**
     * 根据插件id停止插件
     *
     * @param id 插件id
     * @return 返回操作结果
     */
    @PostMapping("/stop/{id}")
    @ApiOperation("停止插件")
    @ApiImplicitParam(name = "id", value = "插件id", paramType = "path", required = true)
    public Result<String> stop(@PathVariable("id") String id) {
        try {
            if (pluginOperator.stop(id)) {
                return Result.response(ApiEnum.OPERATE_SUCCESS, "停止成功");
            } else {
                return Result.response(ApiEnum.OPERATE_ERROR, "停止失败");
            }
        } catch (Exception e) {
            log.error("停止插件 '{}' 失败.", id, e);
            return Result.response(ApiEnum.OPERATE_ERROR, "停止失败." + e.getMessage());
        }
    }

    /**
     * 上传并安装插件。注意: 该操作只适用于生产环境
     *
     * @param multipartFile 插件jar文件
     * @return 操作结果
     */
    @PostMapping("/install")
    @ApiOperation("安装插件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pluginJarFile", value = "插件jar包文件", paramType = "from", required = true),
            @ApiImplicitParam(name = "pluginConfigFile", value = "插件包对应的配置文件(如果存在则上传)", paramType = "from")
    })
    public Result<String> install(@RequestParam("pluginJarFile") MultipartFile multipartFile) {
        try {
            UploadParam uploadParam = UploadParam.byMultipartFile(multipartFile)
                    .setBackOldPlugin(true)
                    .setStartPlugin(true)
                    .setUnpackPlugin(false);
            PluginInfo pluginInfo = pluginOperator.uploadPlugin(uploadParam);
            if (pluginInfo != null) {
                return Result.response(ApiEnum.OPERATE_SUCCESS, "安装并启动成功");
            } else {
                return Result.response(ApiEnum.OPERATE_ERROR, "安装失败");
            }
        } catch (Exception e) {
            log.error("安装插件失败.", e);
            return Result.response(ApiEnum.OPERATE_ERROR, "安装插件失败." + e.getMessage());
        }
    }


    /**
     * 根据插件id卸载插件
     *
     * @param id 插件id
     * @return 返回操作结果
     */
    @PostMapping("/uninstall/{id}")
    @ApiOperation("卸载插件")
    @ApiImplicitParam(name = "id", value = "插件id", paramType = "path", required = true)
    public Result<String> uninstall(@PathVariable("id") String id) {
        try {
            pluginOperator.uninstall(id, true, true);
            return Result.response(ApiEnum.OPERATE_SUCCESS, "卸载成功");

        } catch (Exception e) {
            e.printStackTrace();
            return Result.response(ApiEnum.OPERATE_ERROR, "卸载插件失败." + e.getMessage());
        }

    }
}
